/*//信息位8192 校验位1024
//位宽32
//编码0~255
//解码0~287
//编码输入256（信息），返回32（校验）
//解码输入288（信息加校验），返回288（信息加校验）
module ldpc_top(
//时钟复位
i_clk,
i_rst_n,
//编解码使能
i_code_en,
i_decode_en,
//编解码完成
o_code_finish,
o_decode_finish,
o_decode_error,
//dpram
i_r_clk,
i_w_clk,
i_r_en,
i_w_en,
i_r_addr,
i_w_addr,
i_w_data,
o_r_data
);

//时钟复位
input         i_clk;
input         i_rst_n;
//编解码使能
input         i_code_en;
input         i_decode_en;
//编解码完成
output        o_code_finish;
output        o_decode_finish;
output        o_decode_error;
//dpram
input         i_r_clk;
input         i_w_clk;
input         i_r_en;
input         i_w_en;
input  [8:0]  i_r_addr;
input  [8:0]  i_w_addr;
input  [0:31] i_w_data;
output [0:31] o_r_data;
//ldpc_dpram
wire   [8:0]  ldpc_r_addr;
wire   [8:0]  ldpc_w_addr;
wire   [0:31] ldpc_w_data;
wire   [0:31] ldpc_r_data;
//编解码输出数据地址
wire   [0:31] code_final_data;
wire   [0:31] decode_final_data;
wire   [8:0]  code_addr;
wire   [8:0]  decode_addr;
//ldpc时钟
wire          ldpc_clk;

//ldpc控制器
ldpc_cntrl u_ldpc_cntrl(
    //时钟复位
    .i_clk(i_clk),
    .i_rst_n(i_rst_n),
    //写时钟写使能
    .i_w_clk(i_w_clk),
    .i_w_en(i_w_en),
    //编解码使能
    .i_code_en(i_code_en),
    .i_decode_en(i_decode_en),
    .i_decode_finish(i_decode_finish),
    //编解码地址和数据
    .i_code_addr(code_addr),
    .i_decode_addr(decode_addr),
    .i_code_final_data(code_final_data),
    .i_decode_final_data(decode_final_data),
    //ldpc时钟和读写地址数据
    .o_ldpc_clk(ldpc_clk),
    .o_ldpc_r_addr(ldpc_r_addr),
    .o_ldpc_w_addr(ldpc_w_addr),
    .o_ldpc_w_data(ldpc_w_data)
);

//接口写入，ldpc读出
ldpc_dpram u_dpram_1(
    .i_r_clk(ldpc_clk),
    .i_w_clk(i_w_clk),
    .i_r_en(1'b1),
    .i_w_en(i_w_en),
    .i_r_addr(ldpc_r_addr),
    .i_w_addr(i_w_addr),
    .i_w_data(i_w_data),
    .o_r_data(ldpc_r_data) 
);

//ldpc写入，接口读出
ldpc_dpram u_dpram_2(
    .i_r_clk(i_r_clk),
    .i_w_clk(ldpc_clk),
    .i_r_en(i_r_en),
    .i_w_en(1'b1),
    .i_r_addr(i_r_addr),
    .i_w_addr(ldpc_w_addr),
    .i_w_data(ldpc_w_data),
    .o_r_data(o_r_data) 
);

//编码顶层
code_top u_code_top(
    //时钟复位
    .i_clk(ldpc_clk),
    .i_rst_n(i_rst_n),
    //编码使能
    .i_code_en(i_code_en),
    //输入数据
    .i_code_data(ldpc_r_data),
    //编码完成，输出地址数据
    .o_code_finish(o_code_finish),
    .o_code_addr(code_addr),
    .o_code_final_data(code_final_data)
);

//解码顶层
decode_top u_decode_top(
    //时钟复位
    .i_clk(ldpc_clk),
    .i_rst_n(i_rst_n),
    //解码使能
    .i_decode_en(i_decode_en),
    //输入数据
    .i_decode_data(ldpc_r_data),
    //解码完成和错误
    .o_decode_finish(o_decode_finish),
    .o_decode_error(o_decode_error),
    //输出地址数据
    .o_decode_addr(decode_addr),
    .o_decode_data(decode_final_data)
);

endmodule*/
//信息位8192 校验位1024
//位宽32
//编码0~255
//解码0~287
//编码输入256（信息），返回32（校验）
//解码输入288（信息加校验），返回288（信息加校验）
module ldpc_top(
//时钟复位
i_clk,
i_rst_n,
//编解码使能
i_code_en,
i_decode_en,
//编解码完成
o_code_finish,
o_decode_finish,
o_decode_error,
//dpram
i_r_clk,
i_w_clk,
i_r_en,
i_w_en,
i_r_addr,
i_w_addr,
i_w_data,
o_r_data
);

//时钟复位
input         i_clk;
input         i_rst_n;
//编解码使能
input         i_code_en;
input         i_decode_en;
//编解码完成
output reg    o_code_finish;
output reg    o_decode_finish;
output        o_decode_error;
//dpram
input         i_r_clk;
input         i_w_clk;
input         i_r_en;
input         i_w_en;
input  [8:0]  i_r_addr;
input  [8:0]  i_w_addr;
input  [0:31] i_w_data;
output [0:31] o_r_data;
//ldpc_dpram
wire   [8:0]  ldpc_r_addr;
wire   [8:0]  ldpc_w_addr;
wire   [0:31] ldpc_w_data;
wire   [0:31] ldpc_r_data;
reg    [8:0]  r_cnt;

//接口写入，ldpc读出
ldpc_dpram u_dpram_1(
.i_r_clk(i_clk),
.i_w_clk(i_w_clk),
.i_r_en(1'b1),
.i_w_en(i_w_en),
.i_r_addr(ldpc_r_addr),
.i_w_addr(i_w_addr),
.i_w_data(i_w_data),
.o_r_data(ldpc_r_data) 
);

//ldpc写入，接口读出
ldpc_dpram u_dpram_2(
.i_r_clk(i_r_clk),
.i_w_clk(i_clk),
.i_r_en(i_r_en),
.i_w_en(1'b1),
.i_r_addr(i_r_addr),
.i_w_addr(ldpc_w_addr),
.i_w_data(ldpc_w_data),
.o_r_data(o_r_data) 
);

//输入数据计数
always @(posedge i_w_clk or negedge i_rst_n)
if(!i_rst_n)begin
    r_cnt <= 9'b0-1'b1;
end
else if(i_code_en)begin//编码
    if(i_w_en)begin
        if(r_cnt == 9'd255)begin
            r_cnt <= r_cnt;
        end
        else begin
            r_cnt <= r_cnt + 1'b1;
        end
    end
end
else if(i_decode_en)begin//解码
    if(i_w_en)begin
        if(r_cnt == 9'd287)begin
            r_cnt <= r_cnt;
        end
        else begin
            r_cnt <= r_cnt + 1'b1;
        end
    end
end
else begin
    r_cnt <= 9'b0-1'b1;
end

//延时计数器
reg [8:0] delay_cnt;
always @(posedge i_clk or negedge i_rst_n)
if(!i_rst_n)begin
    delay_cnt <= 9'b0;
end
else if(i_code_en && r_cnt == 9'd255)begin
    if(delay_cnt == 9'd100)begin
        delay_cnt <= delay_cnt;
    end
    else begin
        delay_cnt <= delay_cnt + 1'b1;
    end
end
else if(i_decode_en && r_cnt == 9'd287)begin
    if(delay_cnt == 9'd100)begin
        delay_cnt <= delay_cnt;
    end
    else begin
        delay_cnt <= delay_cnt + 1'b1;
    end
end
else begin
    delay_cnt <= 9'b0;
end

//完成信号
always @(posedge i_clk or negedge i_rst_n)
if(!i_rst_n)begin
    o_code_finish   <= 1'b0;
    o_decode_finish <= 1'b0;
end
else if(i_code_en && delay_cnt == 9'd100)begin
    o_code_finish   <= 1'b1;
end
else if(i_decode_en && delay_cnt == 9'd100)begin
    o_decode_finish <= 1'b1;
end
else begin
    o_code_finish   <= 1'b0;
    o_decode_finish <= 1'b0;
end

assign ldpc_w_addr = i_w_addr;
assign ldpc_w_data = i_w_data;

//输出数据地址
// always @(posedge i_clk or negedge i_rst_n)
// if(!i_rst_n)begin
//     ldpc_w_addr <= 9'b0;
// end
// else if(i_code_en && r_cnt == 9'd255)begin
//     if(ldpc_w_addr == 9'd31)begin
//         ldpc_w_addr <= ldpc_w_addr;
//     end
//     else begin
//         ldpc_w_addr <= ldpc_w_addr + 1'b1;
//     end
// end
// else if(i_decode_en && r_cnt == 9'd287)begin
//     if(ldpc_w_addr == 9'd287)begin
//         ldpc_w_addr <= ldpc_w_addr;
//     end
//     else begin
//         ldpc_w_addr <= ldpc_w_addr + 1'b1;
//     end
// end
// else begin
//     ldpc_w_addr <= 9'b0;
// end

//输出数据
// always @(negedge i_clk or negedge i_rst_n)
// if(!i_rst_n)begin
//     ldpc_w_data <= 32'b0;
// end
// else if(i_code_en && r_cnt == 9'd255)begin
//     ldpc_w_data <= ldpc_w_addr;
// end
// else if(i_decode_en && r_cnt == 9'd287)begin
//     ldpc_w_data <= ldpc_w_addr;
// end
// else begin
//     ldpc_w_data <= 32'b0;
// end



endmodule

